<template>
  <div class="production-table">
    <div class="table-header">
      <div class="status-info">
        <span v-if="!loading && !error && total > 0" class="success-text">
          获取生产信息成功，共 {{ total }} 条记录
        </span>
        <span v-if="!loading && !error && total === 0" class="warning-text">
          暂无生产信息数据
        </span>
      </div>
      <div class="table-actions">
        <button class="refresh-button" @click="getProductionInfos" :disabled="loading">刷新</button>
        <button class="add-button" @click="showAddDialog">新增</button>
        <button class="delete-button" @click="deleteSelected" :disabled="selectedItems.length === 0">删除</button>
      </div>
    </div>
    <div v-if="loading" class="loading-container">
      <div class="loading">数据加载中，请稍候...</div>
    </div>
    <div v-else-if="error" class="error-container">
      <div class="error">{{ error }}</div>
    </div>
    <div v-else-if="total === 0" class="empty-container">
      <div class="empty">暂无生产信息数据</div>
    </div>
    
    <div v-else class="table-scroll-container">
      <table>
        <thead>
          <tr class="header-row">
            <th class="checkbox-cell">
              <input type="checkbox" :checked="isAllSelected" @change="toggleSelectAll" />
            </th>
            <th>商品名称</th>
            <th>生产批次</th>
            <th>保质期（天）</th>
            <th>生产许可证号</th>
            <th>生产企业</th>
            <th>创建人</th>
            <th>修改人</th>
            <th>创建时间</th>
            <th>修改时间</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="(item, index) in paginatedData" :key="index" :class="{ 'selected-row': isSelected(item.id) }">
            <td class="checkbox-cell">
              <input type="checkbox" :checked="isSelected(item.id)" @change="toggleSelect(item)" />
            </td>
            <td>{{ getGoodsName(item.goodsId) }}</td>
            <td>{{ item.batchNumber || '-' }}</td>
            <td>{{ item.shelfLifeDays }}</td>
            <td>{{ item.productionLicenseNumber || '-' }}</td>
            <td>{{ item.manufacturerName || '-' }}</td>
            <td>{{ item.createdBy || '-' }}</td>
            <td>{{ item.modifiedBy || '-' }}</td>
            <td>{{ formatDateTime(item.createdTime) }}</td>
            <td>{{ formatDateTime(item.modifiedTime) }}</td>
            <td class="operation-cell">
              <button class="op-button view-button" @click="viewDetail(item)">查看</button>
              <button class="op-button edit-button" @click="editItem(item)">修改</button>
              <button class="op-button edit-button" @click="exportTraceCode(item)" :disabled="exportLoading">
                {{ exportLoading ? '导出中...' : '导出溯源码' }}
              </button>
              <button class="op-button delete-button-small" @click="confirmDelete(item)">删除</button>
            </td>
          </tr>
        </tbody>
      </table>
    </div>

    <!-- 分页组件 -->
    <div v-if="!loading && !error && total > 0" class="pagination-container">
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="[10, 20, 50, 100]"
        :total="total"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        background
      />
    </div>

    <div v-if="selectedItems.length > 0" class="selection-info">
      已选择 {{ selectedItems.length }} 项
    </div>
    
    <!-- 新增对话框 -->
    <div v-if="showDialog" class="dialog-overlay" @click="closeDialog">
      <div class="dialog-content" @click.stop>
        <div class="dialog-header">
          <h3>基本信息</h3>
          <button class="close-button" @click="closeDialog">×</button>
        </div>
        <div class="dialog-body">
          <div class="form-row">
            <div class="form-label">
              <span class="required">*</span>商品名称：
            </div>
            <div class="form-input">
              <select v-model="formData.goodsId" class="form-select" :disabled="goodsLoading">
                <option value="0" disabled>{{ goodsLoading ? '加载中...' : '请选择商品' }}</option>
                <option v-for="item in goodsList" :key="item.goodsId" :value="item.goodsId">
                  {{ item.goodsName }}
                </option>
              </select>
            </div>
          </div>
          
          <div class="form-row">
            <div class="form-label">
              <span class="required">*</span>生产批次：
            </div>
            <div class="form-input">
              <input
                type="text"
                v-model="formData.batchNumber"
                placeholder="请输入生产批次（最多30个字符）"
                maxlength="30"
                @input="validateBatchNumber"
                :class="{ error: validationErrors.batchNumber }"
              />
              <div v-if="validationErrors.batchNumber" class="error-message">
                {{ validationErrors.batchNumber }}
              </div>
            </div>
          </div>
          
          <div class="form-row">
            <div class="form-label">
              <span class="required">*</span>保质期（天）：
            </div>
            <div class="form-input">
              <input
                type="text"
                v-model="formData.shelfLifeDays"
                placeholder="请输入保质期天数（最多5位数字）"
                maxlength="5"
                @input="validateShelfLifeDays"
                @keypress="onlyNumbers"
                :class="{ error: validationErrors.shelfLifeDays }"
              />
              <div v-if="validationErrors.shelfLifeDays" class="error-message">
                {{ validationErrors.shelfLifeDays }}
              </div>
            </div>
          </div>
          
          <div class="form-row">
            <div class="form-label">
              <span class="required">*</span>生产许可证号：
            </div>
            <div class="form-input">
              <input type="text" v-model="formData.productionLicenseNumber" placeholder="请输入生产许可证号" />
            </div>
          </div>
          
          <div class="form-row">
            <div class="form-label">
              <span class="required">*</span>生产企业：
            </div>
            <div class="form-input">
              <input
                type="text"
                v-model="formData.manufacturerName"
                placeholder="请输入生产企业（最多30个字符，不含特殊字符）"
                maxlength="30"
                @input="validateManufacturerName"
                :class="{ error: validationErrors.manufacturerName }"
              />
              <div v-if="validationErrors.manufacturerName" class="error-message">
                {{ validationErrors.manufacturerName }}
              </div>
            </div>
          </div>
    <!-- 单图上传 -->
    <div class="image-upload-container">
      <div class="form-label">
        <span class="required">*</span>产品图片：
      </div>
      <div class="image-upload-content">
        <el-upload
          class="upload-demo"
          action="http://localhost:34405/api/Image/upload"
          :show-file-list="false"
          :on-success="handleEditImgSuccess"
          :on-error="handleError"
          :before-upload="beforeUpload"
          name="file"
          accept="image/*"
          method="post"
          :headers="uploadHeaders"
        >
          <div v-if="!editForm.picture" class="upload-placeholder">
            <div class="upload-icon">📷</div>
            <div class="upload-text">点击上传图片</div>
            <div class="upload-hint">支持 JPG、PNG、GIF、BMP 格式，大小不超过 5MB</div>
          </div>
          <div v-else class="image-preview">
            <img :src="editForm.picture" class="preview-image" alt="产品图片" />
            <div class="image-overlay">
              <span class="change-text">点击更换图片</span>
            </div>
          </div>
        </el-upload>
        <div v-if="editForm.picture" class="image-info">
          <div class="image-url">
            <span class="url-label">图片地址：</span>
            <a :href="editForm.picture" target="_blank" class="url-link">{{ editForm.picture }}</a>
          </div>
        </div>
      </div>
    </div>

    <!-- 上传结果 -->
    <!-- <div v-if="uploadStatus" class="upload-result" :class="uploadStatus.type">
      <el-alert
        :title="uploadStatus.message"
        :type="uploadStatus.type"
        show-icon
      />
    </div> -->
  </div>
        <div class="dialog-footer">
          <button class="submit-button" @click="submitForm">保存</button>
        </div>
      </div>
    </div>
  </div>

</template>

<script setup lang="ts">
import { ref, onMounted, computed, reactive } from 'vue'
import { useRouter } from 'vue-router'
import { apiWreit } from '@/Ulter/AxiosHepler'
import { ElMessage, ElPagination } from 'element-plus'

import * as XLSX from 'xlsx'
import { UserManager } from '@/utils/userManager'

const router = useRouter()

// 单图上传相关


// 单图上传相关
const editForm=ref({
  picture:''
})

// 添加上传所需的headers
const uploadHeaders = computed(() => {
  const token = localStorage.getItem('token')
  return token ? { 'Authorization': `Bearer ${token}` } : {}
})

// 处理单图上传成功
function handleEditImgSuccess(response: any) {
  console.log('上传响应:', response);
  if (response && response.data) {
    // 根据API返回格式获取图片URL
    const imageUrl = response.data;

    // 检查返回的URL是否已经是完整的URL（包含http://或https://）
    if (imageUrl.startsWith('http://') || imageUrl.startsWith('https://')) {
      // 如果是完整URL，直接使用
      editForm.value.picture = imageUrl;
    } else {
      // 如果是相对路径，则添加服务器地址
      editForm.value.picture = "http://localhost:34405" + imageUrl;
    }

    // 同时更新formData中的coverImageUrl，确保表单提交时包含此字段
    formData.coverImageUrl = imageUrl;
    ElMessage.success('上传成功！');
  } else {
    ElMessage.error('上传失败，未返回图片地址');
  }
}

// 处理上传错误
const handleError = (error:any) => {
  console.error('上传错误:', error);
  ElMessage.error('上传失败，请检查网络或服务器状态');
}

// 上传前的验证
const beforeUpload = (file:any) => {
  // 检查文件类型
  const isImage = ['image/jpeg', 'image/png', 'image/gif', 'image/bmp'].includes(file.type)
  if (!isImage) {
    ElMessage.error('只能上传JPG/PNG/GIF/BMP格式的图片!')
    return false
  }
  
  // 检查文件大小（限制为5MB）
  const isLessThan5M = file.size / 1024 / 1024 < 5
  if (!isLessThan5M) {
    ElMessage.error('图片大小不能超过5MB!')
    return false
  }
  
  return true
}
// 商品数据接口
interface GoodsItem {
  goodsId: number;
  goodsName: string;
  description?: string | null;
}

// 更新ProductionInfo接口以匹配API文档的ProductionInfoDTO
interface ProductionInfo {
  id: string;
  batchNumber: string | null;
  shelfLifeDays: number;
  productionLicenseNumber: string | null;
  manufacturerName: string | null;
  coverImageUrl: string | null;
  goodsId: number;
  createdBy: string | null;
  modifiedBy: string | null;
  operatedBy:string | null;
  createdTime: string;
  modifiedTime: string | null;
}



const loading = ref(true)
const error = ref<string | null>(null)
const selectedItems = ref<string[]>([]) // 存储选中项的id
const goodsList = ref<GoodsItem[]>([]) // 存储商品列表
const goodsLoading = ref(false) // 商品列表加载状态

// 分页相关变量
const currentPage = ref(1) // 当前页码
const pageSize = ref(10) // 每页显示条数
const total = ref(0) // 总记录数
const allData = ref<ProductionInfo[]>([]) // 存储所有数据

// 导出功能相关变量
const exportLoading = ref(false)

// 表单验证错误状态
const validationErrors = ref({
  batchNumber: '',
  shelfLifeDays: '',
  manufacturerName: ''
})

// 对话框相关
const showDialog = ref(false)
const dialogTitle = ref('新增生产信息')
const dialogMode = ref<'add' | 'edit'>('add')
// 恢复原始的表单数据结构，但添加类型注解
const formData = reactive({
  id: '' as string | number,
  batchNumber: '',
  shelfLifeDays: 0,
  productionLicenseNumber: '',
  manufacturerName: '',
  coverImageUrl: null as string | null,
  goodsId: 0
});
// 图片上传




// 计算分页数据
const paginatedData = computed(() => {
  const start = (currentPage.value - 1) * pageSize.value
  const end = start + pageSize.value
  return allData.value.slice(start, end)
})

// 判断是否全选（基于当前页数据）
const isAllSelected = computed(() => {
  return paginatedData.value.length > 0 && selectedItems.value.length === paginatedData.value.length
})

// 判断某项是否被选中
const isSelected = (id: string): boolean => {
  return selectedItems.value.includes(id)
}

// 切换选择状态
const toggleSelect = (item: ProductionInfo) => {
  const index = selectedItems.value.indexOf(item.id)
  if (index === -1) {
    selectedItems.value.push(item.id)
  } else {
    selectedItems.value.splice(index, 1)
  }
}

// 全选/取消全选（仅针对当前页）
const toggleSelectAll = () => {
  if (isAllSelected.value) {
    // 取消选择当前页的所有项
    const currentPageIds = paginatedData.value.map(item => item.id)
    selectedItems.value = selectedItems.value.filter(id => !currentPageIds.includes(id))
  } else {
    // 选择当前页的所有项
    const currentPageIds = paginatedData.value.map(item => item.id)
    const newSelectedItems = [...selectedItems.value]
    currentPageIds.forEach(id => {
      if (!newSelectedItems.includes(id)) {
        newSelectedItems.push(id)
      }
    })
    selectedItems.value = newSelectedItems
  }
}

// 分页处理函数
const handleSizeChange = (newSize: number) => {
  pageSize.value = newSize
  currentPage.value = 1 // 重置到第一页
  updateTableData()
}

const handleCurrentChange = (newPage: number) => {
  currentPage.value = newPage
  updateTableData()
}

// 更新表格数据（用于分页）
const updateTableData = () => {
  // 这里不需要重新获取数据，因为我们使用计算属性paginatedData
  // 只需要确保选中状态正确
}

// 删除选中项
const deleteSelected = async () => {
  if (selectedItems.value.length === 0) return;
  
  if (!confirm(`确定要删除选中的 ${selectedItems.value.length} 条记录吗？此操作无法撤销。`)) {
    return;
  }
  
  // 显示删除进度
  ElMessage.info(`开始删除 ${selectedItems.value.length} 条记录...`);
  
  // 获取当前登录用户作为操作人
  const operatedBy = UserManager.getOperator();
  
  try {
    // 准备批量删除请求的数据
    // 根据错误信息修改数据格式，使用正确的结构
    const batchDeleteData = {
      productionInfoIds: selectedItems.value,
      operatedBy: operatedBy
    };
    
    console.log('批量删除数据:', batchDeleteData);
    
    // 批量删除API端点
    const batchDeleteUrl = `/api/Mange/BatchDeleteProductionInfos/production-info/batch-delete`;
    
    // 发送批量删除请求
    const response = await apiWreit.post(batchDeleteUrl, batchDeleteData, {
      headers: {
        'Content-Type': 'application/json'
      }
    });
    
    console.log('批量删除响应:', response);
    
    if (response.status === 200 || response.status === 204) {
      // 从所有数据中移除选中的项
      allData.value = allData.value.filter(item => !selectedItems.value.includes(item.id));
      total.value = allData.value.length;

      // 检查当前页是否还有数据，如果没有则回到上一页
      const maxPage = Math.ceil(total.value / pageSize.value);
      if (currentPage.value > maxPage && maxPage > 0) {
        currentPage.value = maxPage;
      }

      // 清空选择
      selectedItems.value = [];

      // 显示成功消息
      ElMessage.success(`成功删除 ${batchDeleteData.productionInfoIds.length} 条记录`);
    } else {
      throw new Error(`批量删除失败，服务器返回状态码: ${response.status}`);
    }
  } catch (error: any) {
    console.error('批量删除失败:', error);
    // 尝试解析更详细的错误信息
    let errorMessage = error.message || '未知错误';
    if (error.response && error.response.data) {
      const responseData = error.response.data;
      if (typeof responseData === 'string') {
        errorMessage = responseData;
      } else if (responseData.message) {
        errorMessage = responseData.message;
      } else if (responseData.error) {
        errorMessage = responseData.error;
      }
      console.error('错误详情:', responseData);
    }
    
    ElMessage.error(`批量删除失败: ${errorMessage}`);
    
    // 即使API调用失败，也从UI中移除选中的项，提供更好的用户体验
    allData.value = allData.value.filter(item => !selectedItems.value.includes(item.id));
    total.value = allData.value.length;

    // 检查当前页是否还有数据
    const maxPage = Math.ceil(total.value / pageSize.value);
    if (currentPage.value > maxPage && maxPage > 0) {
      currentPage.value = maxPage;
    }

    selectedItems.value = [];
    ElMessage.warning('数据已在界面上移除，但可能未从数据库中删除');
  }
};

// 确认删除单个项（物理删除）
const confirmDelete = async (item: ProductionInfo) => {
  const goodsName = getGoodsName(item.goodsId)
  if (confirm(`确定要删除"${goodsName || '未知商品'}"(批次:${item.batchNumber || '未知'})的记录吗？此操作无法撤销。`)) {
    try {
      // 获取当前登录用户作为操作人
      const operatedBy = UserManager.getOperator()

      // 使用ProductionSoftDelete接口进行物理删除
      const deleteUrl = `/api/ProductionSoftDelete/${item.id}?operator=${encodeURIComponent(operatedBy)}`;

      console.log('删除URL:', deleteUrl);

      // 发送DELETE请求进行物理删除
      const response = await apiWreit.delete(deleteUrl);

      console.log('删除响应:', response);

      if (response.status === 200 || response.status === 204) {
        ElMessage.success('删除成功');
        // 从所有数据中移除此项
        allData.value = allData.value.filter(i => i.id !== item.id);
        total.value = allData.value.length;

        // 检查当前页是否还有数据
        const maxPage = Math.ceil(total.value / pageSize.value);
        if (currentPage.value > maxPage && maxPage > 0) {
          currentPage.value = maxPage;
        }
      } else {
        throw new Error(`服务器返回状态码: ${response.status}`);
      }
    } catch (error: any) {
      console.error('删除失败:', error);

      // 尝试解析更详细的错误信息
      let errorMessage = error.message || '未知错误';
      if (error.response && error.response.data) {
        const responseData = error.response.data;
        if (typeof responseData === 'string') {
          errorMessage = responseData;
        } else if (responseData.message) {
          errorMessage = responseData.message;
        } else if (responseData.error) {
          errorMessage = responseData.error;
        }
        console.error('错误详情:', responseData);
      }

      ElMessage.error(`删除失败: ${errorMessage}`);

      // 即使API调用失败，也在前端移除数据以提高用户体验
      allData.value = allData.value.filter(i => i.id !== item.id);
      total.value = allData.value.length;

      // 检查当前页是否还有数据
      const maxPage = Math.ceil(total.value / pageSize.value);
      if (currentPage.value > maxPage && maxPage > 0) {
        currentPage.value = maxPage;
      }

      ElMessage.warning('数据已在界面上移除，但可能未从数据库中删除');
    }
  }
};

// 查看详情
const viewDetail = (item: ProductionInfo) => {
  // 跳转到TBDetails页面并传递id参数
  router.push({
    path: '/TBDetails',
    query: {
      id: item.id,
      batchNumber: item.batchNumber,
      goodsId: item.goodsId,
      
    }
  })
}

// 获取商品列表
const getGoodsList = async () => {
  goodsLoading.value = true
  
  try {
    // 发送API请求获取商品列表
    const response = await apiWreit.get('/api/Mange/GetGoods/goods')
    
    // 处理响应
    if (response.status === 200 && response.data && Array.isArray(response.data.data)) {
      goodsList.value = response.data.data
      console.log('成功获取商品列表:', goodsList.value.length, '条记录')
    } else {
      console.warn('API返回的商品数据格式不正确或为空')
      goodsList.value = []
    }
  } catch (err: any) {
    console.error('获取商品列表失败:', err)
    goodsList.value = []
  } finally {
    goodsLoading.value = false
  }
}


  const editItem = (item: ProductionInfo) => {
  // 设置对话框状态
  dialogMode.value = 'edit';
  dialogTitle.value = '编辑生产信息';
  showDialog.value = true;
  
  // 一次性设置所有表单数据
  Object.assign(formData, item);
  
  // 设置图片预览
  if (item.coverImageUrl) {
    // 检查URL是否已经是完整的URL（包含http://或https://）
    if (item.coverImageUrl.startsWith('http://') || item.coverImageUrl.startsWith('https://')) {
      // 如果是完整URL，直接使用
      editForm.value.picture = item.coverImageUrl;
    } else {
      // 如果是相对路径，则添加服务器地址
      editForm.value.picture = "http://localhost:34405" + item.coverImageUrl;
    }
  } else {
    editForm.value.picture = '';
  }
};

// 修改submitForm方法处理编辑逻辑
const submitForm = async () => {
  // 基本验证
  if (!formData.goodsId || !formData.batchNumber || formData.shelfLifeDays <= 0) {
    ElMessage.warning('请填写必填项');
    return;
  }
  // 生产批次验证 - 最多30个字符
  const batchNumberRegex = /^.{0,30}$/;
  if(!batchNumberRegex.test(formData.batchNumber)){
     ElMessage.error("生产批次最多输入30个字符");
     return;
  }

  // 保质期天数验证 - 只允许数字且最多5位
  const numberRegex = /^0|[1-9][0-9]*$/;
  const max5DigitsRegex = /^\d{0,5}$/;
  const shelfLifeDaysStr = String(formData.shelfLifeDays);
  if(!numberRegex.test(shelfLifeDaysStr)){
    ElMessage.error('保质期天数只允许输入数字');
    return;
  }
  if(!max5DigitsRegex.test(shelfLifeDaysStr)){
    ElMessage.error('保质期天数最多支持输入5位数字');
    return;
  }

  // 生产厂家名称验证
  const specialCharsRegex = /[,.?!@#$%^&*()+=\[\]{}|\\:";'<>\/~`]/;
  const manufacturerLengthRegex = /^.{0,30}$/;

  if(specialCharsRegex.test(formData.manufacturerName)){
    ElMessage.error('生产厂家名称不允许输入特殊字符（逗号、问号等）');
    return;
  }
  if(!manufacturerLengthRegex.test(formData.manufacturerName)){
    ElMessage.error('生产厂家名称最多输入30个字符');
    return;
  }

  try {
    // 准备统一数据结构
    const payload = {
      ...formData,
      // 根据不同模式设置不同字段
      ...(dialogMode.value === 'add'
        ? { createdBy: UserManager.getOperator() }
        : { operatedBy: UserManager.getOperator() })
    };
    
    let response;
    
    if (dialogMode.value === 'add') {
      // 添加模式
      response = await apiWreit.post('/api/Mange/AddProductionInfo/production-info', payload);
      if (response && response.status === 200) {
        ElMessage.success('添加成功');
      }
    } else {
    
      // 编辑模式
       // 编辑模式
  const payload = {
    ...formData,
    modifiedBy: UserManager.getOperator()
  };
      response = await apiWreit.put(`/api/ProductionUpdate`, payload);
      if (response && response.status === 200) {
        ElMessage.success('修改成功');
      }
    }
    
    getProductionInfos();
    closeDialog();
  } catch (error) {
    console.error('操作失败:', error);
    ElMessage.error('操作失败');
  }
};

// 根据goodsId获取商品名称
const getGoodsName = (goodsId: number): string => {
  const good = goodsList.value.find(item => item.goodsId === goodsId)
  return good ? good.goodsName : '-'
}

// 导出溯源码功能
const exportTraceCode = async (item: ProductionInfo) => {
  if (!item || !item.id) {
    ElMessage.warning('数据不完整，无法导出')
    return
  }

  exportLoading.value = true

  try {
    console.log('开始导出溯源码，生产信息ID:', item.id)

    // 使用 /api/ProductionUpdate/{id} 接口获取详细的生产信息（与TBDetails.vue保持一致）
    const productionUrl = `/api/ProductionUpdate/${item.id}`

    // 发送请求获取生产信息详情
    const response = await apiWreit.get(productionUrl, {
      headers: {
        'Accept': 'application/json'
      }
    })

    console.log('生产信息API响应:', response)

    if (response.status === 200 && response.data) {
      // 获取详细的生产信息数据
      const productionData = response.data.data || response.data
      console.log('获取到的生产信息详情:', productionData)

      // 生成文件名
      const goodsName = getGoodsName(item.goodsId) || '未知商品'
      const batchNumber = item.batchNumber || productionData.batchNumber || '未知批次'
      const filename = `${goodsName}_${batchNumber}_溯源码.xlsx`

      // 创建Excel数据结构
      const excelData = [
        // 标题行
        ['溯源码信息表'],
        [''], // 空行

        // 基本信息部分
        ['基本信息'],
        ['商品名称', goodsName],
        ['生产批次', batchNumber],
        ['生产信息ID', productionData.id || item.id],
        [''], // 空行

        // 生产详情部分
        ['生产详情'],
        ['保质期', `${productionData.shelfLifeDays || item.shelfLifeDays}天`],
        ['生产许可证号', productionData.productionLicenseNumber || item.productionLicenseNumber || '无'],
        ['生产企业', productionData.manufacturerName || item.manufacturerName || '无'],
        ['商品ID', productionData.goodsId || item.goodsId],
        [''], // 空行

        // 时间信息部分
        ['时间信息'],
        ['创建时间', productionData.createdTime || item.createdTime],
        ['修改时间', productionData.modifiedTime || item.modifiedTime || '无'],
        [''], // 空行

        // 图片信息部分
        ['图片信息'],
        ['封面图片', productionData.coverImageUrl ? `http://localhost:34405${productionData.coverImageUrl}` : '无'],
        [''], // 空行

        // 元数据部分
        ['生成信息'],
        ['生成时间', new Date().toLocaleString('zh-CN')],
        ['数据来源', `/api/ProductionUpdate/${item.id} API接口`]
      ]

      // 创建工作簿和工作表
      const workbook = XLSX.utils.book_new()
      const worksheet = XLSX.utils.aoa_to_sheet(excelData)

      // 设置列宽
      const columnWidths = [
        { wch: 15 }, // A列：标签列
        { wch: 30 }  // B列：数据列
      ]
      worksheet['!cols'] = columnWidths

      // 设置单元格样式（标题行）
      if (worksheet['A1']) {
        worksheet['A1'].s = {
          font: { bold: true, sz: 16 },
          alignment: { horizontal: 'center' }
        }
      }

      // 设置分类标题样式
      const categoryRows = [3, 8, 15, 19, 22] // 基本信息、生产详情、时间信息、图片信息、生成信息的行号
      categoryRows.forEach(row => {
        const cellRef = `A${row}`
        if (worksheet[cellRef]) {
          worksheet[cellRef].s = {
            font: { bold: true, sz: 12 },
            fill: { fgColor: { rgb: 'E6F3FF' } }
          }
        }
      })

      // 将工作表添加到工作簿
      XLSX.utils.book_append_sheet(workbook, worksheet, '溯源码信息')

      // 生成Excel文件并下载
      const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' })
      const blob = new Blob([excelBuffer], {
        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      })

      const downloadUrl = window.URL.createObjectURL(blob)
      const link = document.createElement('a')
      link.href = downloadUrl
      link.download = filename
      document.body.appendChild(link)
      link.click()

      // 清理
      document.body.removeChild(link)
      window.URL.revokeObjectURL(downloadUrl)

      ElMessage.success('Excel溯源码导出成功！')
      console.log('Excel文件下载完成:', filename)

    } else {
      throw new Error(`获取生产信息失败，服务器返回状态码: ${response.status}`)
    }
  } catch (error: any) {
    console.error('导出溯源码失败:', error)

    // 处理不同类型的错误
    let errorMessage = '导出失败'

    if (error.response) {
      // 服务器返回了错误响应
      if (error.response.status === 404) {
        errorMessage = '生产信息不存在或已被删除'
      } else if (error.response.status === 400) {
        errorMessage = '请求参数错误，请检查数据完整性'
      } else if (error.response.status === 500) {
        errorMessage = '服务器内部错误，请稍后重试'
      } else {
        errorMessage = `导出失败 (${error.response.status})`
      }
    } else if (error.request) {
      // 请求发送了但没有收到响应
      errorMessage = '网络连接失败，请检查网络状态'
    } else {
      // 其他错误
      errorMessage = error.message || '未知错误'
    }

    ElMessage.error(errorMessage)
  } finally {
    exportLoading.value = false
  }
}

// 显示新增对话框
const showAddDialog = () => {
  dialogMode.value = 'add'
  dialogTitle.value = '新增生产信息'
  
  // 重置表单数据
  formData.id = 0
  formData.batchNumber = ''
  formData.shelfLifeDays = 0
  formData.productionLicenseNumber = ''
  formData.manufacturerName = ''
  formData.coverImageUrl = null
  formData.goodsId = 0
  
  // 重置图片
  editForm.value.picture = '';
  
  showDialog.value = true
}
// 关闭对话框
const closeDialog = () => {
  showDialog.value = false
  // 关闭时清除验证错误
  clearValidationErrors()
}

// 清除验证错误
const clearValidationErrors = () => {
  validationErrors.value = {
    batchNumber: '',
    shelfLifeDays: '',
    manufacturerName: ''
  }
}

// 生产批次验证
const validateBatchNumber = () => {
  const value = formData.batchNumber
  if (!value) {
    validationErrors.value.batchNumber = ''
    return
  }

  if (value.length > 30) {
    validationErrors.value.batchNumber = '生产批次最多输入30个字符'
  } else {
    validationErrors.value.batchNumber = ''
  }
}

// 保质期天数验证
const validateShelfLifeDays = () => {
  const value = String(formData.shelfLifeDays)
  if (!value) {
    validationErrors.value.shelfLifeDays = ''
    return
  }

  const numberRegex = /^0|[1-9][0-9]*$/
  const max5DigitsRegex = /^\d{0,5}$/

  if (!numberRegex.test(value)) {
    validationErrors.value.shelfLifeDays = '只允许输入数字'
  } else if (!max5DigitsRegex.test(value)) {
    validationErrors.value.shelfLifeDays = '最多支持输入5位数字'
  } else {
    validationErrors.value.shelfLifeDays = ''
  }
}

// 生产厂家名称验证
const validateManufacturerName = () => {
  const value = formData.manufacturerName
  if (!value) {
    validationErrors.value.manufacturerName = ''
    return
  }

  const specialCharsRegex = /[,.?!@#$%^&*()+=\[\]{}|\\:";'<>\/~`]/

  if (specialCharsRegex.test(value)) {
    validationErrors.value.manufacturerName = '不允许输入特殊字符（逗号、问号等）'
  } else if (value.length > 30) {
    validationErrors.value.manufacturerName = '生产厂家名称最多输入30个字符'
  } else {
    validationErrors.value.manufacturerName = ''
  }
}

// 只允许输入数字
const onlyNumbers = (event: KeyboardEvent) => {
  const char = event.key
  if (!/[0-9]/.test(char) && char !== 'Backspace' && char !== 'Delete' && char !== 'Tab' && char !== 'Enter') {
    event.preventDefault()
  }
}






const formatDateTime = (dateTimeStr: string | null): string => {
  if (!dateTimeStr) return '-'
  const date = new Date(dateTimeStr)
  return date.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  })
}



// 获取产品信息
const getProductionInfos = async () => {
  loading.value = true
  error.value = null
  selectedItems.value = [] // 重置选择
  currentPage.value = 1 // 重置到第一页
  
  try {
    // 发送API请求获取产品信息
    const response = await apiWreit.get('/api/Mange/GetAllProductionInfos/production-info')
    
    // 处理响应
    if (response.status === 200) {
      
      if (response.data && response.data.data && Array.isArray(response.data.data)) {
        // 使用API返回的数据
        const processedData = response.data.data.map((item: any) => ({
          ...item,
          // 确保goodsId存在，如果API返回的是goodsName但没有goodsId
          goodsId: item.goodsId || 0
        }))

        // 存储所有数据和设置总数
        allData.value = processedData
        total.value = processedData.length

        // tableData现在通过计算属性paginatedData来获取
        console.log('成功获取产品信息:', total.value, '条记录')
      } else {
        // 如果API返回的数据格式不正确或为空
        console.warn('API返回的数据格式不正确或为空')
        allData.value = []
        total.value = 0
        throw new Error('没有可用的产品信息数据')
      }
    } else {
      // 处理非200状态码
      throw new Error(`API返回非200状态码: ${response.status}`)
    }
  } catch (err: any) {
    console.error('获取产品信息失败:', err)
    error.value = err.message || '获取产品信息失败'
    allData.value = []
    total.value = 0
    
    // 如果是401错误，可能是未登录或token无效
    if (err.response && err.response.status === 401) {
      console.warn('未授权(401错误)，可能是未登录或token无效');
      ElMessage.error('请先登录或重新登录');
    } else {
      // 显示错误消息
      ElMessage.error(`获取数据失败: ${error.value}`);
    }
  } finally {
    loading.value = false
  }
}

onMounted(() => {
  getProductionInfos()
  getGoodsList() // 获取商品列表
})
</script>

<style scoped>
.production-table {
  width: 100%;
  font-size: 14px;
  background-color: #f5f5f5;
}

/* 表格滚动容器 */
.table-scroll-container {
  width: 100%;
  overflow-x: auto;
  overflow-y: visible;
  background-color: white;
  border-radius: 4px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
  /* 自定义滚动条样式 */
  scrollbar-width: thin;
  scrollbar-color: #c1c1c1 #f1f1f1;
}

/* Webkit浏览器滚动条样式 */
.table-scroll-container::-webkit-scrollbar {
  height: 8px;
}

.table-scroll-container::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 4px;
}

.table-scroll-container::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 4px;
}

.table-scroll-container::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

/* 响应式设计 - 在小屏幕上优化滚动体验 */
@media (max-width: 768px) {
  .table-scroll-container {
    /* 在移动设备上显示滚动提示 */
    position: relative;
  }

  .table-scroll-container::after {
    content: '← 左右滑动查看更多 →';
    position: absolute;
    bottom: -25px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 12px;
    color: #999;
    white-space: nowrap;
  }

  /* 在移动设备上增加滚动条高度 */
  .table-scroll-container::-webkit-scrollbar {
    height: 12px;
  }
}

.table-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px;
  background-color: white;
  margin-bottom: 16px;
  border-radius: 4px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
}

.status-info {
  font-size: 14px;
}

.success-text {
  color: #52c41a;
  font-weight: bold;
}

.warning-text {
  color: #faad14;
  font-weight: bold;
}

.table-actions {
  display: flex;
  gap: 8px;
}

.add-button {
  background-color: #1890ff;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  display: flex;
  align-items: center;
}

.add-button:hover {
  background-color: #40a9ff;
}

.delete-button {
  background-color: #ff4d4f;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  display: flex;
  align-items: center;
}

.delete-button:hover {
  background-color: #ff7875;
}

.delete-button:disabled {
  background-color: #d9d9d9;
  cursor: not-allowed;
}

.refresh-button {
  background-color: #52c41a;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  display: flex;
  align-items: center;
}

.refresh-button:hover {
  background-color: #73d13d;
}

.refresh-button:disabled {
  background-color: #d9d9d9;
  cursor: not-allowed;
}

table {
  min-width: 1200px; /* 设置表格最小宽度，确保所有列都有足够空间 */
  width: 100%;
  border-collapse: collapse;
  table-layout: auto; /* 改为auto以便列宽自适应内容 */
  background-color: white;
}

.header-row {
  background-color: #e6e6e6;
  height: 40px;
}

.header-row th {
  padding: 8px;
  text-align: center;
  font-weight: normal;
  border: 1px solid #d9d9d9;
  white-space: nowrap; /* 防止表头文字换行 */
}

/* 设置各列的最小宽度 */
.header-row th:nth-child(1) { min-width: 50px; }  /* 复选框 */
.header-row th:nth-child(2) { min-width: 120px; } /* 商品名称 */
.header-row th:nth-child(3) { min-width: 100px; } /* 生产批次 */
.header-row th:nth-child(4) { min-width: 100px; } /* 保质期 */
.header-row th:nth-child(5) { min-width: 140px; } /* 生产许可证号 */
.header-row th:nth-child(6) { min-width: 120px; } /* 生产企业 */
.header-row th:nth-child(7) { min-width: 80px; }  /* 创建人 */
.header-row th:nth-child(8) { min-width: 80px; }  /* 修改人 */
.header-row th:nth-child(9) { min-width: 150px; } /* 创建时间 */
.header-row th:nth-child(10) { min-width: 150px; } /* 修改时间 */
.header-row th:nth-child(11) { min-width: 280px; } /* 操作 */

tbody tr {
  height: 40px;
}

tbody tr:nth-child(even) {
  background-color: #f9f9f9;
}

tbody tr:nth-child(odd) {
  background-color: #ffffff;
}

tbody tr.selected-row {
  background-color: #e6f7ff;
}

tbody td {
  padding: 8px;
  text-align: center;
  border: 1px solid #e8e8e8;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 设置数据行各列的最小宽度，与表头保持一致 */
tbody td:nth-child(1) { min-width: 50px; }  /* 复选框 */
tbody td:nth-child(2) { min-width: 120px; } /* 商品名称 */
tbody td:nth-child(3) { min-width: 100px; } /* 生产批次 */
tbody td:nth-child(4) { min-width: 100px; } /* 保质期 */
tbody td:nth-child(5) { min-width: 140px; } /* 生产许可证号 */
tbody td:nth-child(6) { min-width: 120px; } /* 生产企业 */
tbody td:nth-child(7) { min-width: 80px; }  /* 创建人 */
tbody td:nth-child(8) { min-width: 80px; }  /* 修改人 */
tbody td:nth-child(9) { min-width: 150px; } /* 创建时间 */
tbody td:nth-child(10) { min-width: 150px; } /* 修改时间 */
tbody td:nth-child(11) { min-width: 280px; } /* 操作 */

.checkbox-cell {
  width: 40px;
  text-align: center;
}

.operation-cell {
  display: flex;
  justify-content: center;
  gap: 8px;
  flex-wrap: nowrap; /* 防止按钮换行 */
  align-items: center;
}

.op-button {
  padding: 4px 8px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  border: 1px solid #d9d9d9;
  background-color: #fff;
}

.op-button:hover {
  background-color: #e6f7ff;
  border-color: #91d5ff;
}

.op-button:active {
  background-color: #bae7ff;
}

.op-button.view-button {
  color: #1890ff;
  border-color: #91d5ff;
}

.op-button.edit-button {
  color: #faad14;
  border-color: #ffe58f;
}

.op-button.delete-button-small {
  color: #ff4d4f;
  border-color: #ffa39e;
}

.op-button.delete-button-small:hover {
  background-color: #fffbe6;
  border-color: #ffe58f;
}

.op-button.delete-button-small:active {
  background-color: #fff1f0;
  border-color: #ffa39e;
}

.dialog-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.dialog-content {
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
  width: 90%;
  max-width: 800px;
  max-height: 90%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.dialog-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px;
  border-bottom: 1px solid #eee;
  background-color: #f5f5f5;
}

.dialog-header h3 {
  margin: 0;
  font-size: 18px;
  color: #333;
  font-weight: bold;
}

.close-button {
  background-color: transparent;
  border: none;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 24px;
  color: #888;
}

.close-button:hover {
  color: #555;
}

.dialog-body {
  padding: 16px;
  flex-grow: 1;
  overflow-y: auto;
}

.form-row {
  display: flex;
  margin-bottom: 24px;
  align-items: center;
}

.form-label {
  width: 150px;
  text-align: right;
  padding-right: 12px;
  font-size: 14px;
  color: #333;
}

.form-input {
  flex: 1;
  position: relative;
}

.loading-indicator {
  position: absolute;
  top: 100%;
  left: 0;
  font-size: 12px;
  color: #1890ff;
  padding: 4px 0;
}

.required {
  color: #ff4d4f;
  margin-right: 4px;
}

.form-input input {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  font-size: 14px;
  box-sizing: border-box;
}

.form-input input:focus {
  outline: none;
  border-color: #40a9ff;
  box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}

.form-select {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  font-size: 14px;
  box-sizing: border-box;
  appearance: auto;
  background-color: white;
}

.form-select:focus {
  outline: none;
  border-color: #40a9ff;
  box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}

.form-select option {
  padding: 8px;
}

.dialog-footer {
  padding: 16px;
  border-top: 1px solid #eee;
  display: flex;
  justify-content: center;
}

.dialog-footer .submit-button {
  background-color: #1890ff;
  color: white;
  border: none;
  padding: 12px 32px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 16px;
}

.dialog-footer .submit-button:hover {
  background-color: #40a9ff;
}

.dialog-footer .submit-button:disabled {
  background-color: #d9d9d9;
  cursor: not-allowed;
  color: #888;
}

.loading-container, .error-container, .empty-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 200px;
  background-color: white;
  border-radius: 4px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
}

.loading {
  text-align: center;
  padding: 20px;
  font-size: 16px;
  color: #1890ff;
}

.error {
  text-align: center;
  padding: 20px;
  font-size: 16px;
  color: #ff4d4f;
}

.empty {
  text-align: center;
  padding: 20px;
  font-size: 16px;
  color: #999;
}

/* 分页容器样式 */
.pagination-container {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px 0;
  background-color: white;
  border-radius: 4px;
  margin-top: 16px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
}

.selection-info {
  margin-top: 16px;
  padding: 8px;
  background-color: #f0f5ff;
  border-radius: 4px;
  color: #1890ff;
  font-weight: bold;
}

.url-input {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  font-size: 14px;
}

.url-input:focus {
  outline: none;
  border-color: #40a9ff;
  box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}

.upload-box {
  width: 100px;
  height: 100px;
  border: 1px dashed #d9d9d9;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  background-color: #f5f5f5;
}

.upload-box:hover {
  border-color: #40a9ff;
  background-color: #e6f7ff;
}

.preview-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgba(0, 0, 0, 0.5);
}

.preview-image {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.remove-button {
  position: absolute;
  top: 5px;
  right: 5px;
  background-color: rgba(0, 0, 0, 0.5);
  color: white;
  border: none;
  border-radius: 50%;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 16px;
}

.remove-button:hover {
  background-color: rgba(0, 0, 0, 0.7);
}

.placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.upload-icon {
  font-size: 24px;
  margin-bottom: 8px;
}

.upload-text {
  font-size: 12px;
}


.upload-container {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
}

.upload-section {
  margin-bottom: 30px;
  padding: 20px;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  background-color: #f8f9fa;
}

.image-uploader {
  width: 178px;
  height: 178px;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: border-color 0.3s;
}

.image-uploader:hover {
  border-color: #409eff;
}

.image-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}

.uploaded-image {
  width: 178px;
  height: 178px;
  display: block;
  object-fit: cover;
}

.image-info {
  margin-top: 10px;
}

.upload-result {
  margin-top: 20px;
}

h2 {
  color: #303133;
  margin-bottom: 20px;
}

h3 {
  color: #606266;
  margin-bottom: 15px;
}

/* 表单验证错误样式 */
.error-message {
  color: #f56c6c;
  font-size: 12px;
  margin-top: 4px;
  line-height: 1.4;
}

.form-input input.error {
  border-color: #f56c6c;
}

.form-input input:focus.error {
  border-color: #f56c6c;
  box-shadow: 0 0 0 2px rgba(245, 108, 108, 0.2);
}

/* 图片上传样式 */
.image-upload-container {
  display: flex;
  margin-bottom: 24px;
  align-items: flex-start;
}

.image-upload-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.upload-placeholder {
  width: 150px;
  height: 150px;
  border: 2px dashed #d9d9d9;
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.3s ease;
  background-color: #fafafa;
}

.upload-placeholder:hover {
  border-color: #40a9ff;
  background-color: #e6f7ff;
}

.upload-icon {
  font-size: 48px;
  margin-bottom: 8px;
  color: #8c939d;
}

.upload-text {
  font-size: 14px;
  color: #606266;
  margin-bottom: 4px;
  font-weight: 500;
}

.upload-hint {
  font-size: 12px;
  color: #909399;
  text-align: center;
  line-height: 1.4;
}

.image-preview {
  position: relative;
  width: 150px;
  height: 150px;
  border-radius: 8px;
  overflow: hidden;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.preview-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.3s ease;
}

.image-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.image-preview:hover .image-overlay {
  opacity: 1;
}

.image-preview:hover .preview-image {
  transform: scale(1.05);
}

.change-text {
  color: white;
  font-size: 14px;
  font-weight: 500;
}

.image-info {
  margin-top: 12px;
  width: 100%;
  max-width: 400px;
}

.image-url {
  padding: 8px 12px;
  background-color: #f5f5f5;
  border-radius: 4px;
  border: 1px solid #e4e7ed;
}

.url-label {
  font-size: 12px;
  color: #606266;
  font-weight: 500;
}

.url-link {
  font-size: 12px;
  color: #409eff;
  text-decoration: none;
  word-break: break-all;
  line-height: 1.4;
}

.url-link:hover {
  text-decoration: underline;
}











</style>
